1 /** 2 * License: 3 * Copyright Devisualization (Richard Andrew Cattermole) 2014 - 2017. 4 * Distributed under the Boost Software License, Version 1.0. 5 * (See accompanying file LICENSE_1_0.txt or copy at 6 * http://www.boost.org/LICENSE_1_0.txt) 7 */ 8 module devisualization.util.core.assetmanager; 9 10 /** 11 * Loads assest based upon, local to program, defaults, application provided, system locatiom and user location. 12 * Supports bin2d's generated modules to load from. 13 */ 14 deprecated("An asset manager should be based upon a VFS.") 15 struct AssetManager(T) { 16 private __gshared { 17 T[string] local; 18 T[string] defaults; 19 T[string] apps; 20 T[string] systems; 21 T[string] users; 22 23 string localPath, userPath, systemPath; 24 } 25 26 this(string dirIndex, string app, string company = null, string customSystemInstallDirectory=null) { 27 import std.path : buildPath, baseName; 28 import std.process : environment; 29 localPath = buildPath(dirIndex); 30 31 version(Windows) { 32 if (company is null) { 33 userPath = buildPath(environment["LOCALAPPDATA"], app, dirIndex); 34 35 if (customSystemInstallDirectory is null) 36 systemPath = buildPath(environment["PROGRAMFILES"], app, dirIndex); 37 else 38 systemPath = buildPath(customSystemInstallDirectory, app, dirIndex); 39 } else { 40 userPath = buildPath(environment["LOCALAPPDATA"], company, app, dirIndex); 41 if (customSystemInstallDirectory is null) 42 systemPath = buildPath(environment["PROGRAMFILES"], company, app, dirIndex); 43 else 44 systemPath = buildPath(customSystemInstallDirectory, company, app, dirIndex); 45 } 46 } else version(Posix) { 47 if (company is null) { 48 userPath = buildPath(environment["HOME"], app, dirIndex); 49 50 if (customSystemInstallDirectory is null) 51 programFilesPath = buildPath("/usr/share", app, dirIndex); 52 else 53 programFilesPath = buildPath(customSystemInstallDirectory, app, dirIndex); 54 } else { 55 userPath = buildPath(environment["HOME"], company, app, dirIndex); 56 57 if (customSystemInstallDirectory is null) 58 programFilesPath = buildPath("/usr/share", company, app, dirIndex); 59 else 60 programFilesPath = buildPath(customSystemInstallDirectory, company, app, dirIndex); 61 } 62 } else { 63 static assert(0, "Have not implemented storage locations for platform."); 64 } 65 66 update(); 67 } 68 69 /** 70 * Registers a default assest value provided by the application 71 * 72 * Params: 73 * mod = Name of assest 74 * value = The value of the asset 75 */ 76 void registerDefault(string mod, T value) { defaults[mod] = value; } 77 78 /** 79 * Registers an assest value provided by the application 80 * 81 * Params: 82 * mod = Name of asset 83 * value = The value of the asset 84 */ 85 void registerApp(string mod, T value) { apps[mod] = value; } 86 87 /** 88 * Registers application assets that was compiled in via Bin2d 89 * 90 * Params: 91 * filterExtension = Extension of files to only use 92 * asDefault = Is this a default value or application override? Default: true (default value) 93 */ 94 void registerFromBin2d(string bin2dmod)(string filterExtension, bool asDefault=true) { 95 import std.algorithm : canFind; 96 import std..string : tr; 97 import std.path : extension; 98 mixin("import " ~ bin2dmod ~ ";"); 99 100 foreach(i, fn; assetNames) { 101 string oname = assetOriginalNames[i]; 102 if (oname.extension == filterExtension) { 103 if (asDefault) 104 registerDefault(oname, cast(T)assetValues[i]); 105 else 106 registerApp(oname, cast(T)assetValues[i]); 107 } 108 } 109 } 110 111 /** 112 * Gets an assest based upon its name 113 * 114 * Params: 115 * mod = Name of asset 116 */ 117 T opIndex(string mod) { 118 if (mod in local) return local[mod]; 119 if (mod in apps) return apps[mod]; 120 if (mod in users) return users[mod]; 121 if (mod in systems) return systems[mod]; 122 return defaults.get(mod, T.init); 123 } 124 125 /** 126 * Updates all files from the file system. 127 * Looks in local to application, user application directories and system application directories 128 */ 129 void update() { 130 local = getFilesFromFileSystem(localPath); 131 users = getFilesFromFileSystem(userPath); 132 systems = getFilesFromFileSystem(systemPath); 133 } 134 135 private { 136 import std.file : exists, mkdirRecurse, isDir, dirEntries, SpanMode, read, FileException; 137 import std.path : baseName; 138 139 T[string] getFilesFromFileSystem(string dir) 140 in { 141 try { 142 if (exists(dir)) { 143 if (isDir(dir)) { 144 // directory exists. 145 } else { 146 // I don't know how to handle this *shrugs* 147 } 148 } else { 149 mkdirRecurse(dir); 150 } 151 } catch (Error e) { 152 } catch (Exception e) { 153 } 154 } body { 155 T[string] ret; 156 if (exists(dir) && isDir(dir)) { 157 // once we get here we already _know_ the directory exists 158 foreach(string entry; dirEntries(dir, SpanMode.shallow)) { 159 ret[baseName(entry)] = cast(T)read(entry); 160 } 161 } 162 return ret; 163 } 164 } 165 }